package com.qc31.monitorlib.ui.singlemap

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.view.View
import androidx.activity.viewModels
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import autodispose2.autoDispose
import com.amap.api.maps.AMap
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.LatLngBounds
import com.amap.api.maps.model.Marker
import com.amap.api.maps.model.PolylineOptions
import com.gyf.immersionbar.ktx.immersionBar
import com.qc31.baselib.databinding.IncludeToolbarBinding
import com.qc31.baselib.rx.LiveDataBus
import com.qc31.baselib.rx.queryThrottle
import com.qc31.baselib.utils.*
import com.qc31.baselib.utils.ActivityResultUtil.launchAct
import com.qc31.baselib.utils.ActivityResultUtil.registerResultOk
import com.qc31.comlib.Keys
import com.qc31.comlib.NetDataUtil
import com.qc31.comlib.UserConstant
import com.qc31.comlib.choose.car.ChooseCarActivity
import com.qc31.comlib.entity.GpsDetail
import com.qc31.monitorlib.login.LocationStatusModel
import com.qc31.monitorlib.ui.popup.ChooseNaviPopup
import com.qc31.monitorlib.R
import com.qc31.monitorlib.base.BaseMapActivity
import com.qc31.monitorlib.databinding.ActivitySingleMapBinding
import com.qc31.monitorlib.databinding.IncludeCarMapInfoBinding
import com.qc31.monitorlib.databinding.IncludeMapPlateTrafficBinding
import com.qc31.monitorlib.ui.adapter.CarInfoAdapter
import com.qc31.monitorlib.ui.carinfo.CarInfoActivity
import com.qc31.monitorlib.ui.line.HistoryLineActivity
import com.qc31.monitorlib.ui.other.InfoSetActivity
import com.qc31.monitorlib.ui.photo.PhotosActivity
import com.qc31.monitorlib.ui.popup.SingleMapTimePopup
import com.qc31.monitorlib.ui.video.RealVideoActivity
import com.qc31.monitorlib.uitls.ColorUtil
import com.qc31.monitorlib.uitls.MapUtil
import com.qc31.monitorlib.uitls.MarkerBitmapUtil

/** @Author Jasper @Time 2020/12/4 @Desc */
class SingleMonitorActivity :
    BaseMapActivity<ActivitySingleMapBinding>(ActivitySingleMapBinding::inflate) {
    private lateinit var mMapStateVB: IncludeMapPlateTrafficBinding
    private lateinit var mBarVB: IncludeToolbarBinding
    private lateinit var mInfoVB: IncludeCarMapInfoBinding
    private var mMarker: Marker? = null

    //最后一个定位点坐标
    private var lastLatLng: LatLng? = null
    private var startLatLng: LatLng? = null
    private var endLatLng: LatLng? = null

    //是否开始跟踪
    private var isStart = false

    //是否展示彈窗
    private var isShowPopup = true

    //定位点集合
    private val lines = ArrayList<LatLng>()
    private val mOption: PolylineOptions by lazy { PolylineOptions() }

    private val mNaviPopup by lazy { ChooseNaviPopup(this) }

    private val mTimePopup by lazy {
        SingleMapTimePopup(this, object : SingleMapTimePopup.OnTimeCallBack {
            override fun onBack(time: Long) {
                mViewModel.saveRefreshTime(time)
                if (isStart) {
                    mViewModel.stopTime()
                    mViewModel.startTime()
                }
            }

        })
    }

    private val mViewModel: SingleMapViewModel by viewModels()
    override fun initMap() {

        initMapSetting()
    }

    override fun initView() {
        mMapStateVB = IncludeMapPlateTrafficBinding.bind(binding.root)
        mBarVB = IncludeToolbarBinding.bind(binding.root)
        mInfoVB = IncludeCarMapInfoBinding.bind(binding.root)
        ToolbarHelper.setToolbar(this, R.string.title_monitor_single)
        immersionBar { titleBar(mBarVB.mToolbar) }
        mMapStateVB.tvCarCarState.visibility = View.GONE
        initViewModel()
        initIntent()
        infoView()
        infoEvent()
    }

    private fun initIntent() {
        val carId = intent.getStringExtra(Keys.INTENT_CAR_ID)
        val carName = intent.getStringExtra(Keys.INTENT_PLATE) ?: ""
        if (carId == null) return
        mViewModel.carId = carId
        binding.lrvChooseCar.setRightText(carName)
        isStart = true
        mViewModel.startTime()
        binding.lrvChooseCar.isEnabled = false
    }

    private fun initMapSetting() {
        mAMap.run {
            MapUtil.initMapSetting(this)
            setOnMarkerClickListener {
                if (it.`object` == "marker")
                    return@setOnMarkerClickListener true
                isShowPopup = true
                mMapStateVB.tvCarCarShow.setText(R.string.desc_com_hide)
                mInfoVB.llCarInfo.visibility = View.VISIBLE
                return@setOnMarkerClickListener true
            }
            mapType = mViewModel.mMapType
            isTrafficEnabled = mViewModel.isCarTraffic
        }
    }

    //是否已显示
    private var isShow = false
    private fun initViewModel() {
        if (mViewModel.isCarName) {
            mMapStateVB.tvCarCarState.setText(R.string.desc_car_name)
        } else {
            mMapStateVB.tvCarCarState.setText(R.string.desc_car_plate)
        }
        mViewModel.toastObserver().autoDispose(scopeProvider).subscribe(this::toastObserver)

        mViewModel.locationSub.hide().autoDispose(scopeProvider).subscribe({
            it.run {
                if (glat.isEmpty() || glng.isEmpty()) return@subscribe
                if (!isShow) {
                    toast(R.string.toast_single_start)
                    binding.btnSingleEnd.isSelected = true
                    binding.btnSingleStart.isSelected = false
                    isShow = true
                }
                val latLng = LatLng(it.glat.toDouble(), it.glng.toDouble())
                lastLatLng = latLng
                addLineOption(latLng)

                val bitmapDes =
                    MarkerBitmapUtil.getBitmapDes(
                        this@SingleMonitorActivity,
                        carId, state, drct, carName, carPlate, iconLink, mViewModel.isCarName, speed
                    )
                if (mMarker == null) {
                    MapUtil.addGetMarker(
                        mAMap,
                        latLng,
                        if (Language.instance.isEnglish()) R.mipmap.ic_marker_start_e else R.mipmap.ic_marker_start
                    ).`object` =
                        "marker"
                    mMarker = MapUtil.addAndGetMarker(mAMap, latLng, bitmapDes)
                    startLatLng = latLng
                } else {
                    mMarker?.position = latLng
                    mMarker?.setIcon(bitmapDes)
                }
                if (isShowPopup) {
                    MapUtil.showLatLngZoom(mAMap, latLng)
                    mInfoVB.llCarInfo.visibility = View.VISIBLE
                    initInfo()
                }
            }
        }, {
            toast(it.message ?: getString(R.string.toast_no_back_error_info))
        })
        mViewModel.startLive.observe(this) {
            isStart = false
        }
    }


    override fun setListener() {
        binding.ivCarTimeSet.setOnClickListener {
            mTimePopup.showPopupWindow(window.decorView, mViewModel.time)
        }

        mMapStateVB.tvCarMapState.queryThrottle().autoDispose(scopeProvider).subscribe {
            if (mViewModel.mMapType == AMap.MAP_TYPE_NORMAL) {
                mViewModel.mMapType = AMap.MAP_TYPE_SATELLITE
                mAMap.mapType = AMap.MAP_TYPE_SATELLITE
                mMapStateVB.tvCarMapState.setText(R.string.desc_com_map_state_satellite)
            } else {
                mViewModel.mMapType = AMap.MAP_TYPE_NORMAL
                mAMap.mapType = AMap.MAP_TYPE_NORMAL
                mMapStateVB.tvCarMapState.setText(R.string.desc_com_map_state_normal)
            }
        }

        mMapStateVB.tvCarCarState.queryThrottle().autoDispose(scopeProvider).subscribe {
            mViewModel.isCarName = !mViewModel.isCarName
            if (mViewModel.isCarName) {
                mMapStateVB.tvCarCarState.setText(R.string.desc_car_name)
            } else {
                mMapStateVB.tvCarCarState.setText(R.string.desc_car_plate)
            }
            mViewModel.refresh()
        }

        mMapStateVB.ivCarTraffic.queryThrottle().autoDispose(scopeProvider).subscribe {
            mViewModel.isCarTraffic = !mViewModel.isCarTraffic
            mMapStateVB.ivCarTraffic.isSelected = mViewModel.isCarTraffic
            mAMap.isTrafficEnabled = mViewModel.isCarTraffic

        }

        binding.lrvChooseCar.queryThrottle().autoDispose(scopeProvider).subscribe {

            if (!mViewModel.carId.isNullOrEmpty()) {
                isStart = false
                isShow = false
                binding.btnSingleStart.isSelected = true
                binding.btnSingleEnd.isSelected = false
                mInfoVB.llCarInfo.visibility = View.GONE
                stopMonitor()
                mViewModel.stopTime()
            }
            if (!mViewModel.carId.isNullOrEmpty()) binding.btnSingleStart.isSelected = true
            binding.btnSingleEnd.isSelected = false
            launcher.launchAct<ChooseCarActivity>(this)

        }

        binding.btnSingleStart.queryThrottle().autoDispose(scopeProvider).subscribe {
            if (mViewModel.carId.isNullOrEmpty()) {
                toast(R.string.hint_toast_choose_car)
                return@subscribe
            }
            if (isStart) {
                toast(R.string.toast_single_has_start)
                return@subscribe
            }
            if (!binding.btnSingleStart.isSelected) {
                R.string.toast_no_location_other.toast(this)
                return@subscribe
            }
            mAMap.clear()
            isStart = true
            mViewModel.startTime()
            isShowPopup = true
            mMapStateVB.tvCarCarShow.setText(R.string.desc_com_hide)
        }

        binding.btnSingleEnd.queryThrottle().autoDispose(scopeProvider).subscribe {
            if (mViewModel.carId.isNullOrEmpty()) {
                toast(R.string.hint_toast_choose_car)
                return@subscribe
            }
            if (!isStart) {
                toast(R.string.toast_single_not_start)
                return@subscribe
            }
            isStart = false
            isShow = false
            binding.btnSingleStart.isSelected = true
            binding.btnSingleEnd.isSelected = false
            mInfoVB.llCarInfo.visibility = View.GONE
            toast(R.string.toast_single_stop)
            stopMonitor()
            mViewModel.stopTime()
        }
        mMapStateVB.tvCarCarShow.queryThrottle().autoDispose(scopeProvider).subscribe {
            if (!isStart) {
                toast(R.string.toast_single_not_start)
                return@subscribe
            }
            if (isShowPopup) {
                isShowPopup = false
                mMapStateVB.tvCarCarShow.setText(R.string.desc_com_display)
                mInfoVB.llCarInfo.visibility = View.GONE
            } else {
                isShowPopup = true
                mMapStateVB.tvCarCarShow.setText(R.string.desc_com_hide)
                mInfoVB.llCarInfo.visibility = View.VISIBLE
            }
        }
    }

    /** 划线 */
    private fun addLineOption(latLng: LatLng) {
        lines.add(latLng)
        mOption.color(Color.GREEN).width(15f).add(latLng)
        mAMap.addPolyline(mOption)
    }

    /** 停止 */
    private fun stopMonitor() {
        clearPointsAndMarker()
        lastLatLng?.let {
            MapUtil.addGetMarker(
                mAMap,
                it,
                if (Language.instance.isEnglish()) R.mipmap.ic_marker_end_e else R.mipmap.ic_marker_end
            ).`object` = "marker"
        }
        endLatLng = lastLatLng
        if (startLatLng == null) return
        val builder = LatLngBounds.Builder()
        builder.include(startLatLng)
        builder.include(endLatLng)
        MapUtil.showMapBounds(mAMap, builder.build())
    }

    override fun onDestroy() {
        super.onDestroy()
        clearPointsAndMarker()
        MarkerBitmapUtil.recycleLruCache()
        lastLatLng = null
        lines.clear()
        mViewModel.stopTime()
    }

    private fun clearPointsAndMarker() {
        mOption.points.clear()
        mInfoVB.llCarInfo.visibility = View.GONE
        mMarker?.remove()
        mMarker = null
    }

    private val launcher = registerResultOk { result ->
        result.data?.let {
            mAMap.clear()
            val carId = it.getStringExtra(Keys.INTENT_CAR_ID)
            val carName = it.getStringExtra(Keys.INTENT_CAR_NAME) ?: ""
            binding.lrvChooseCar.setRightText(carName)
            mViewModel.carId = carId
            binding.btnSingleStart.isSelected = true
            isShowPopup = true
            isShow = false
            mMapStateVB.tvCarCarShow.setText(R.string.desc_com_hide)
        }
    }


    //******************************************************************************************************
    private val runSpeed by lazy { getString(R.string.desc_run_speed) }
    private val dayMile by lazy { getString(R.string.desc_day_mile) }

    @SuppressLint("SetTextI18n")
    fun initInfo() {
        mViewModel.gpsDetail?.run {
            mInfoVB.tvPlateName.text = sub(if (mViewModel.isCarName) carName else carPlate, 14)
            mInfoVB.tvCarRunSpeed.text = "$speed km/h\n$runSpeed"
            mInfoVB.tvCarRunStop.text = runStopTime
            mInfoVB.tvCarDayMile.text = "$preMile km\n$dayMile"
            mInfoVB.tvCarTotalMile.text = "$mile km"

            val colorCode: String = if (plateColorCode.isNullOrEmpty()) {
                NetDataUtil.getColorByName(plateColor)
            } else {
                plateColorCode!!
            }
            when (colorCode) {
                "6", "93", "224" -> {
                    mInfoVB.tvPlateName.setBackgroundResource(R.drawable.ic_color_plate_93)
                }
                "94", "225" -> {
                    mInfoVB.tvPlateName.setBackgroundResource(R.drawable.ic_color_plate_94)
                }
                else -> {
                    val colorDrawable = ColorDrawable()
                    colorDrawable.color = Color.parseColor(ColorUtil.getPlateColor(colorCode))
                    mInfoVB.tvPlateName.background = colorDrawable
                }
            }
            mInfoVB.tvPlateName.setTextColor(Color.parseColor(ColorUtil.getPlateTextColor(colorCode)))

            mInfoVB.tvCarTime.text = "${getString(R.string.desc_location_time)}：$time"
            MLog.e("------${UserConstant.isRealVideo}-----${videos.isNullOrEmpty()}-----")
            mInfoVB.tvCarPhoto.text =
                if (!UserConstant.isRealVideo || videos.isNullOrEmpty()) {
                    getString(R.string.desc_marker_photo)
                } else {
                    getString(R.string.desc_single_car_real_video)
                }
        }
        if (isShowRecycler) {
            showInfoRecycler()
        }

    }

    private val mInfoAdapter by lazy { CarInfoAdapter() }
    private fun infoView() {
        mInfoVB.recyclerCarInfo.layoutManager = LinearLayoutManager(this)
        mInfoVB.recyclerCarInfo.adapter = mInfoAdapter
        mInfoVB.tvCarSingle.isVisible = false
        mInfoVB.ivCarShare.isVisible = !BuildConfigs.ISGOOGLE && BuildConfigs.ISCOMPANY
    }

    private fun showInfoRecycler() {
        mInfoAdapter.setList(LocationStatusModel.upData(mViewModel.gpsDetail))
    }

    //是否展示列表
    private var isShowRecycler = false

    /** 设置info点击事件 */
    private fun infoEvent() {
        LiveDataBus.get().with("upInfoState").observe(this) {
            if (mViewModel.carId.isNullOrEmpty()) return@observe
            mViewModel.refresh()
        }
        mInfoVB.ivUpDown.setOnClickListener {
            isShowRecycler = !isShowRecycler
            if (isShowRecycler) {
                showInfoRecycler()
                mInfoVB.recyclerCarInfo.visibility = View.VISIBLE
            } else {
                mInfoVB.recyclerCarInfo.visibility = View.GONE
            }
        }


        mInfoVB.ivUp.setOnClickListener {
            isShowRecycler = !isShowRecycler
            mInfoVB.ivUp.isSelected = isShowRecycler
            if (isShowRecycler) {
                showInfoRecycler()
                mInfoVB.recyclerCarInfo.visibility = View.VISIBLE
            } else {
                mInfoVB.recyclerCarInfo.visibility = View.GONE
            }
        }

        mInfoVB.ivCarSet.setOnClickListener {
            startActivityTo<InfoSetActivity>(this)
        }

        mInfoVB.ivCarClose.setOnClickListener {

            isShowPopup = false
            mMapStateVB.tvCarCarShow.setText(R.string.desc_com_display)
            mInfoVB.llCarInfo.visibility = View.GONE
        }

        mInfoVB.ivCarRefresh.setOnClickListener {
            if (isFastClick()) return@setOnClickListener
            mViewModel.refresh2()
        }

        mInfoVB.tvCarHistory.setOnClickListener {
            startActivity(HistoryLineActivity::class.java, mViewModel.gpsDetail)
        }

        mInfoVB.tvCarPhoto.setOnClickListener {
            val videos = mViewModel.gpsDetail?.videos
            MLog.e("------${UserConstant.isRealVideo}-----${videos.isNullOrEmpty()}-----")
            if (!UserConstant.isRealVideo || videos.isNullOrEmpty()) {
                startActivity(PhotosActivity::class.java, mViewModel.gpsDetail)
            } else
                startActivity(
                    Intent(this, RealVideoActivity::class.java)
                        .putExtra(Keys.INTENT_CAR_ID, mViewModel.gpsDetail?.carId)
                        .putExtra(Keys.INTENT_PLATE, mViewModel.gpsDetail?.carPlate)
                        .putExtra(Keys.INTENT_CAR_NAME, mViewModel.gpsDetail?.carName)
                        .putExtra(Keys.INTENT_CAR_VIDEOS, mViewModel.gpsDetail?.videos)
                )
        }
        mInfoVB.tvCarSingle.setOnClickListener {
            startActivity(SingleMonitorActivity::class.java, mViewModel.gpsDetail)
        }
        mInfoVB.tvCarInfo.setOnClickListener {
            mViewModel.stopTime()
            startActivityTo<CarInfoActivity>(this) {
                putExtra(Keys.INTENT_CAR_ID, mViewModel.carId)
            }
        }

        mInfoVB.tvCarNavi.setOnClickListener {
//            getPermissions()
            mNaviPopup.showAtLocation(window.decorView, mViewModel.gpsDetail)
        }

        mInfoVB.tvCarCall.setOnClickListener {
            if (mViewModel.gpsDetail?.drvPhone.isNullOrEmpty()) {
                R.string.desc_no_phone.toast(this)
            } else {
                //跳转到拨号界面，同时传递电话号码
                val dialIntent =
                    Intent(
                        Intent.ACTION_DIAL,
                        Uri.parse("tel:${mViewModel.gpsDetail?.drvPhone}")
                    )
                startActivity(dialIntent)

            }
        }
        mInfoVB.ivCarShare.setOnClickListener {
//            WxShareUtil.instance.init(applicationContext)
//            mViewModel.locaEntity?.let {
//                wxViewModel.shareLocation(it.carPlate, it.carId)
//            }

        }
    }

//    private val wxViewModel by viewModels<WxShareModel>()

    private fun startActivity(zClass: Class<*>, entity: GpsDetail?) {
        startActivity(
            Intent(this, zClass)
                .putExtra(Keys.INTENT_CAR_ID, entity?.carId)
                .putExtra(Keys.INTENT_PLATE, entity?.carPlate)
                .putExtra(Keys.INTENT_CAR_NAME, entity?.carName)
        )
    }

    override fun onResume() {
        super.onResume()
        if (isStart)
            mViewModel.startTime()
    }
}